package org.song.aspectJ;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.song.model.threadlocal.WebContextUtil;
import org.song.util.FunctionUtil;
import org.song.util.JacksonUtil;
import org.song.util.email.EmailUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

/**
 * 接口请求时间切面记录
 */

@Slf4j
@Aspect
@Component
public class RequestTimeRecordAspect {

    private static final String ALERT_MESSAGE_TITLE = "接口请求超过3秒";

    @Autowired( required = true )
    @Qualifier( value = "emailUtil")
    private EmailUtil emailUtil;

    // 获取统计每个接口请求时间的注解横切关注点
    @Pointcut(value = "@annotation(org.song.annotation.RequestTimeRecord))")
    public void requestTimeRecordPointCut() {

    }

    /**
     * 接口请求时间横切记录
     * @param proceedingJoinPoint
     * @return
     */
    @Around( value = "requestTimeRecordPointCut()")
    public Object requestTimeRecordAspect(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        //目标方法执行前 生成时间
        long beforeTime = System.currentTimeMillis();
        //执行目标方法 (目标方法异常无需处理 SpringMvc 自动处理)
        Object targetMethodReturnValue = proceedingJoinPoint.proceed();
        // 目标方法执行结束
        if ( System.currentTimeMillis() - beforeTime >= 3L * 1000L) {
            final String requestRui = WebContextUtil.getCurrentRequest().getRequestURI();
            final String requestIp = FunctionUtil.getIpAddress( WebContextUtil.getCurrentRequest() );
            final String requestParam = JacksonUtil.getJsonString( proceedingJoinPoint.getArgs() ) ;
            final String emailText = "url: " + requestRui + "\n" + "ip: " + requestIp + "\n" + "requestParam: " + requestParam;
            log.warn("接口请求超时： \n" + emailText );
            // 接口请求时间大于三秒钟 邮件告警
            emailUtil.sendEasyEmail( ALERT_MESSAGE_TITLE , emailText );
        }
        return targetMethodReturnValue;

    }

}
